package com.clinic.logic.userlogin;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.clinic.accessor.db.UserAccessor;
import com.clinic.accessor.db.UserLoginAccessor;
import com.clinic.entity.db.User;
import com.clinic.entity.db.UserLogin;
import com.clinic.entity.gui.GuiUser;
import com.clinic.entity.gui.GuiUserLogin;
import com.clinic.entity.param.SessionUser;

@Component
public class UserLoginLogic {
	
	@Autowired
	private UserLoginAccessor userLoginAcccssor;
	
	@Autowired
	private UserAccessor userAccessor;
	
	public void updateUserLogin(GuiUserLogin guiUserLogin) {
		
		User user = null;
		UserLogin userLogin = userLoginAcccssor.getLoginDetailsByLoginId(guiUserLogin.getLoginId());
		
		if(userLogin != null){
			user = userLogin.getUser();
		} else {
			user = userAccessor.getUserById(guiUserLogin.getUser().getUserId());
		}

		UserLogin oUserLogin = getUserLoginByGuiUserLogin(guiUserLogin, user);
		userLoginAcccssor.insertOrUpdate(oUserLogin);
	}
	
	@Transactional
	public GuiUserLogin getLoginDetailsByUserId(long id) {
		
		User user = null;
		UserLogin userLogin = userLoginAcccssor.getLoginDetailsByUserId(id);
		
		if(userLogin != null) {
			user = userLogin.getUser();
		} else {
			user = userAccessor.getUserById(id);
		}
		return (getGuiUserLoginByUserLogin(userLogin, user));
	}
	
	@Transactional
	public GuiUserLogin getLoginDetailsByUsername(String uname) {
		
		User user = null;
		UserLogin userLogin = userLoginAcccssor.getLoginDetailsByUsername(uname);
		if(userLogin != null){
			user = userLogin.getUser();	
		}		
		return (getGuiUserLoginByUserLogin(userLogin, user));
	}
	
	public boolean isBlankValues(GuiUserLogin guiUserLogin) {
		UserLogin userLogin = userLoginAcccssor.getLoginDetailsByUserId(guiUserLogin.getUser().getUserId());
		
		// check any blank inputs are available
		return StringUtils.isBlank(guiUserLogin.getUsername()) || 
			(userLogin != null && StringUtils.isBlank(guiUserLogin.getOldPassword())) || 
			StringUtils.isBlank(guiUserLogin.getPassword()) || 
			StringUtils.isBlank(guiUserLogin.getConfirmPassword());
	}
	
	public boolean isBlankLoginValues(GuiUserLogin guiUserLogin) {
		
		// check any blank login inputs are available
		return StringUtils.isBlank(guiUserLogin.getUsername()) || 
			   StringUtils.isBlank(guiUserLogin.getPassword());
	}
	
	public boolean isValidUsername(GuiUserLogin guiUserLogin) {
		String uname = guiUserLogin.getUsername();
		UserLogin userLogin = userLoginAcccssor.getLoginDetailsByUsername(uname);
		// not existing username
		boolean isUsernameNotExist = (userLogin == null);
		// username himself
		boolean isUsernameOfCurrentUser = (userLogin != null && userLogin.getLoginId() == guiUserLogin.getLoginId());
		
		return (isUsernameNotExist || isUsernameOfCurrentUser);
	}
	
	public boolean isValidOldPassword(GuiUserLogin guiUserLogin) {
		UserLogin userLogin = userLoginAcccssor.getLoginDetailsByUserId(guiUserLogin.getUser().getUserId());
		// old password not exist
		boolean isOldPasswordNotExist = (userLogin == null);
		// matching old password
		boolean isMatchingOldPassword = (userLogin != null && userLogin.getPassword().equals(guiUserLogin.getOldPassword()));
		
		return (isOldPasswordNotExist || isMatchingOldPassword);
	}
	
	public boolean isValidNewPassword(GuiUserLogin guiUserLogin) {
		UserLogin userLogin = userLoginAcccssor.getLoginDetailsByUserId(guiUserLogin.getUser().getUserId());
		// old password not exist
		boolean isOldPasswordNotExist = (userLogin == null);
		// valid new password
		boolean isValidNewPassword = !(userLogin != null && userLogin.getPassword().equals(guiUserLogin.getPassword()));
		
		return (isOldPasswordNotExist || isValidNewPassword);
	}
	
	public boolean isValidConfirmation(GuiUserLogin guiUserLogin) {
		return (guiUserLogin.getPassword().equals(guiUserLogin.getConfirmPassword()));
	}
	
	public SessionUser getSessionUserByGuiUserLogin(GuiUserLogin guiUserLogin) {
		
		SessionUser sessionUser = new SessionUser();
		sessionUser.setUserId(guiUserLogin.getUser().getUserId());
		sessionUser.setName(guiUserLogin.getUser().getName());
		sessionUser.setType(guiUserLogin.getUser().getUserType());
		sessionUser.setAdmin(guiUserLogin.getUser().isAdmin());
		return sessionUser;
	}
	
	private GuiUserLogin getGuiUserLoginByUserLogin(UserLogin userLogin, User user) {
		
		GuiUserLogin result = new GuiUserLogin();
		
		if(userLogin != null) {			
			result.setLoginId(userLogin.getLoginId());
			result.setUsername(userLogin.getUsername());
			result.setPassword(userLogin.getPassword());
		}
		
		if(user != null) {
			GuiUser guiUser = new GuiUser();
			guiUser.setUserId(user.getUserId());
			guiUser.setName(user.getName());
			guiUser.setType(user.getType().toString());
			guiUser.setAdmin(user.isAdmin());
			result.setUser(guiUser);
		}
		return result;
	}
	
	private UserLogin getUserLoginByGuiUserLogin(GuiUserLogin guiUserLogin, User user) {
		
		UserLogin result = new UserLogin();
		
		if(guiUserLogin != null) {
			result.setLoginId(guiUserLogin.getLoginId());
			result.setUsername(guiUserLogin.getUsername());
			result.setPassword(guiUserLogin.getPassword());
			result.setUser(user);
		}	
		return result;
	}

}
